/**
 * =====================================================================================
 *
 *    @file:  db_relation.h
 *
 *    @brief:  对一个关系数据的抽象接口，此处是接口声明，使用这些接口
 *					应该包含此文件。
 *
 *    @version:  1.0
 *    Created:  2010年04月08日 13时09分45秒
 *    Revision:  none
 *    Compiler:  gcc -Wall -Wextra db_table.h
 *
 *    @author:  easyeagel (LiuGuangBao), easyeagel@gmx.com
 *    Company:  简单C++ - www.easycpp.org
 *
 * =====================================================================================
 */

#ifndef M_magus_db_relation_h
#define M_magus_db_relation_h
#ifdef __cplusplus
#include<cstring>
extern "C"
{
#else
#include<string.h>
#endif

#include"expression.hpp"

typedef struct RLTdelete_t
{

}RLTdelete_t;

typedef struct RLTinsert_t
{

}RLTinsert_t;

typedef struct RLTupdate_t
{
	RLTexpression_t** table; /**< 通常是UTF-8编码的表名列表，以NULL结尾； */
	RLTexpression_t** filed; /**< 字段表达式，是一列赋值表达式 */
	RLTexpression_t* where; /**< where表达式树 */
}RLTupdate_t;

/**
 * @class RLTselect_t
 * @brief 用于一个select查询的结构
 * @todo 设计或选择一个合适的表达式树结构
 * @note 其中的字符串都是UTF-8编码
 */
typedef struct RLTselect_t
{
	RLTexpression_t** table; /**< 通常是UTF-8编码的表名列表，以NULL结尾；以后可能支持虚拟表 */
	RLTexpression_t** filed; /**< 字段表达式，支持计算字段 */
	RLTexpression_t* where; /**< where表达式树 */
	RLTexpression_t** group; /**< group by表达式 */
	RLTexpression_t* order; /**< order by表达式树 */
	RLTexpression_t* limit; /**< limit子句表达式树 */
	unsigned distinct : 1; /**< 一个标志，是否distinct */
}RLTselect_t;

/**
 * @brief openPlant到关系数据库映射层的数据库连接的结构
 * @details 这代表着一个与数据库连接，与数据库任何操作都必需指定一个连接，
 *		如此使用一个进程可以存在多个连接。
 * @note 你不应该手工定义这一个结构，你应该调用rlt_create来创建，调用rlt_close来销毁
 * @see rlt_connect
 * @see rlt_close
 */
typedef struct RLTcntor_t
{
	void* source; /**< 内部使用的资源 */

	const char* server; /**< 服务器地址 */
	unsigned short port; /**< 服务器端口 */
	unsigned long timeout; /**< 连接服务器的超时 */
}RLTcntor_t;

/**
 * @brief 创建一个连接器
 */
RLTcntor_t* rlt_create(const char* server, unsigned short port, unsigned long timeout);

/**
 * @brief 执行与服务器连接
 * @return RLT_yes:成功；RLT_no：失败
 */
int rlt_connect(RLTcntor_t* cntor);

/** 
* @brief 选择一个数据库，以方便后继操作
* 
* @param cntor 连接管理器
* @param name 数据库的名字
* 
* @return RLT_yes:成功；RLT_no：失败
*/
int rlt_use_db(RLTcntor_t* cntor, const char* name);

int rlt_delete(RLTcntor_t* cntor, RLTdelete_t* dlt);
int rlt_insert(RLTcntor_t* cntor, RLTinsert_t* ist);
int rlt_update(RLTcntor_t* cntor, RLTupdate_t* udt);
int rlt_select(RLTcntor_t* cntor, RLTselect_t* slt);

/**
 * @brief 开启缓存在任何时候
 *
 * @return RLT_yes:成功；RLT_no：失败
 */
int rlt_cache(RLTcntor_t* cntor);

/**
 * @brief 关闭缓存在任何时候
 */
void rlt_uncache(RLTcntor_t* cntor);

/**
 * @brief 关闭一个连接
 */
void rlt_close(RLTcntor_t* cntor);

/**
 * @brief 判断一个数库是否存在
 * @param cntor 一个数据库连接
 * @param db_name 需要判断的表名
 * @return RLT_yes: 表存在；RLT_no：表不存在
 */
int rlt_db_is_exist(RLTcntor_t* cntor, const char* db_name);

/**
 * @brief 判断一个表是否存在
 * @param cntor 一个数据库连接
 * @param table_name 需要判断的表名
 * @return RLT_yes: 表存在；RLT_no：表不存在
 */
int rlt_table_is_exist(RLTcntor_t* cntor, const char* table_name);

/**
 * @brief 判断一个字段是否存在
 * @param cntor 一个数据库连接
 * @param filed_name 需要判断的表名
 * @return MACRO_yes: 表存在；MACRO_no：表不存在
 */
int rlt_filed_is_exist(RLTcntor_t* cntor, const char* filed_name);

void rlt_source_print(void* sc);

#ifdef __cplusplus
}
#endif

#endif /* M_magus_db_relation_h */

